package com.blq.developtools.service;

import android.accessibilityservice.AccessibilityService;
import android.content.Context;
import android.content.Intent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import com.blq.developtools.activity.LayoutViewerActivity;
import com.blq.developtools.observerpattern.observable.LayoutViewerObservable;
import com.blq.developtools.observerpattern.observer.ILayoutViewerActionObserve;
import com.blq.developtools.utils.DevelopUtils;
import com.blq.developtools.utils.SystemUtils;
import com.blq.developtools.widget.floathelper.LayoutInspectorWindowHelper;

import blq.ssnb.snbutil.SnbLog;

/**
 * <pre>
 * ****************************************************************
 * 文件名称:DevelopToolsService.java
 * 作 者:SSNB
 * 创建时间:2024/5/14
 * 文件描述:
 * 注意事项:
 * 版权声明:Copyright (C) 2015-2025 杭州中焯信息技术股份有限公司
 * 修改历史:2024/5/14 1.00 初始版本
 * ****************************************************************
 * </pre>
 */
public class DevelopToolsService extends AccessibilityService {

    private static final String BUNDLE_KEY_ACTION = "SSNB_BUNDLE_KEY_ACTION";
    private static final String BUNDLE_KEY_IS_OPEN_LAYOUT_VIEWER = "SSNB_BUNDLE_KEY_IS_OPEN_LAYOUT_VIEWER";
    private static final String BUNDLE_VALUE_ACTION_SHOW_LAYOUT_INSPECTOR = "SSNB_BUNDLE_VALUE_ACTION_SHOW_LAYOUT_INSPECTOR";
    private static final String BUNDLE_VALUE_ACTION_SHOW_SCAN_LAYOUT = "SSNB_BUNDLE_VALUE_ACTION_SHOW_SCAN_LAYOUT";

    private LayoutInspectorWindowHelper layoutInspectorWindowHelper;
    private boolean isLayoutViewerOpen = false;
    private boolean isStopCache = true;
    private boolean isGetLastNodeInfo = false;
    private AccessibilityNodeInfo lastNodeInfo;

    private ILayoutViewerActionObserve observe = new ILayoutViewerActionObserve() {
        @Override
        public void onLayoutInspectorStatus(boolean isOpen) {
            if (!isOpen) {
                layoutInspectorWindowHelper.setMode(false);
            }
        }

        @Override
        public void onLayoutViewerStatus(boolean isOpen) {
            if (isOpen) {
                isLayoutViewerOpen = true;
                isStopCache = true;
            } else {
                isStopCache = false;
                isLayoutViewerOpen = false;
            }
        }

        @Override
        public void onLayoutViewerStatusChange(LayoutViewerStatus status) {
            switch (status) {
                case STATUS_NORMAL:
                    if (layoutInspectorWindowHelper != null) {
                        layoutInspectorWindowHelper.setMode(false);
                    }
                    break;
                case STATUS_SELECT_VIEW:
                case STATUS_VIEW_PROPERTIES:
                default:
                    if (layoutInspectorWindowHelper != null) {
                        layoutInspectorWindowHelper.setMode(true);
                    }

            }

        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        LayoutViewerObservable.getInstance().registerNotify(observe);
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        SnbLog.e(">>>>>event:" + "actionType:" + SystemUtils.getEventTypeString(event.getEventType()) + "; package:" + event.getPackageName() + ":class=" + event.getClassName());
        switch (event.getEventType()) {
            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                handleWindowsChange(event);
                handleNodeInfo(event);
                break;

            case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
                handleNodeInfo(event);
                break;
            case AccessibilityEvent.TYPE_ANNOUNCEMENT:
                break;
            case AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT:
                break;
            case AccessibilityEvent.TYPE_GESTURE_DETECTION_END:
                break;
            case AccessibilityEvent.TYPE_GESTURE_DETECTION_START:
                break;
            case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
                break;
            case AccessibilityEvent.TYPE_SPEECH_STATE_CHANGE:
                break;
            case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END:
                break;
            case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START:
                break;
            case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
                break;
            case AccessibilityEvent.TYPE_TOUCH_INTERACTION_START:
                break;
            case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
                break;
            case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
                break;
            case AccessibilityEvent.TYPE_VIEW_CLICKED:
                break;
            case AccessibilityEvent.TYPE_VIEW_CONTEXT_CLICKED:
                break;
            case AccessibilityEvent.TYPE_VIEW_FOCUSED:
                break;
            case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
                break;
            case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
                break;
            case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED:
                break;
            case AccessibilityEvent.TYPE_VIEW_SCROLLED:
                break;
            case AccessibilityEvent.TYPE_VIEW_SELECTED:
                break;
            case AccessibilityEvent.TYPE_VIEW_TARGETED_BY_SCROLL:
                break;
            case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
                break;
            case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED:
                break;
            case AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
                break;
            case AccessibilityEvent.TYPE_WINDOWS_CHANGED:
                break;
        }


    }

    private void handleWindowsContentChange(AccessibilityEvent event) {
//        AccessibilityNodeInfo ri = getRootInActiveWindow();
//        AccessibilityNodeInfo info = event.getSource();
//        if (info != null) {
//            AccessibilityNodeInfo rootParent = findRootParent(info);
//            Intent intent = new Intent(this, LayoutViewerActivity.class);
//            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            intent.putExtra("xx", rootParent);
//            startActivity(intent);
//        }
    }

    private void handleNodeInfo(AccessibilityEvent event) {
        //打开界面查看器的情况下，
        // 并且没有暂停缓存更新,或者最后的缓存没有
        if (layoutInspectorWindowHelper != null
                && layoutInspectorWindowHelper.isShowing()
                && (!isStopCache || !isGetLastNodeInfo) && !isDevelopApp(event)) {
            lastNodeInfo = getRootInActiveWindow();
            if (isStopCache) {
                openLayoutViewer();
            }
        }
    }

    private AccessibilityNodeInfo findRootParent(AccessibilityNodeInfo info) {
        AccessibilityNodeInfo parent = info.getParent();
        if (parent == null) {
            return info;
        } else {
            return findRootParent(parent);
        }
    }

    private void handleWindowsChange(AccessibilityEvent event) {
        //如果展示的情况下才会更新内容
        if (layoutInspectorWindowHelper != null) {
            if (layoutInspectorWindowHelper.isShowing() && !isDevelopApp(event)) {
                String appName = "未知";
                if (!event.getText().isEmpty()) {
                    appName = DevelopUtils.unNullBean(event.getText().get(0), appName).toString();
                }
                String packageName = event.getPackageName().toString();
                String className = DevelopUtils.unNullBean(event.getClassName(), "").toString();
                layoutInspectorWindowHelper.updateInfo(appName, packageName, className);
            }
        }
    }

    private boolean isDevelopApp(AccessibilityEvent event) {
        return "com.blq.developtools".contentEquals(event.getPackageName());
    }


    @Override
    public void onInterrupt() {

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LayoutViewerObservable.getInstance().unRegisterNotify(observe);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String action = intent.getStringExtra(BUNDLE_KEY_ACTION);
        if (action != null) {
            switch (action) {
                case BUNDLE_VALUE_ACTION_SHOW_LAYOUT_INSPECTOR:
                    openLayoutInspector();
                    break;
                case BUNDLE_VALUE_ACTION_SHOW_SCAN_LAYOUT: {
                    //是否停止缓存
                    isStopCache = intent.getBooleanExtra(BUNDLE_KEY_IS_OPEN_LAYOUT_VIEWER, false);
                    //设置最后的NodeInfo为未获取状态
                    isGetLastNodeInfo = false;
                    if (isStopCache) {
                        openLayoutViewer();
                    }
                }
                break;
            }
        }

        return super.onStartCommand(intent, flags, startId);
    }

    private void openLayoutViewer() {
        if (lastNodeInfo != null) {
            if (isLayoutViewerOpen) {
                return;
            }
            Intent intent = new Intent(this, LayoutViewerActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("xx", lastNodeInfo);
            isGetLastNodeInfo = true;
            isStopCache = true;
            isLayoutViewerOpen = true;
            startActivity(intent);
        } else {
            //如果布局为空，那么认为是没有获取
            isGetLastNodeInfo = false;
        }
    }

    private void openLayoutInspector() {
        if (layoutInspectorWindowHelper == null) {
            layoutInspectorWindowHelper = new LayoutInspectorWindowHelper(this);
            layoutInspectorWindowHelper.build();
        }
        if (!layoutInspectorWindowHelper.isShowing()) {
            layoutInspectorWindowHelper.show();
            LayoutViewerObservable.getInstance().onLayoutInspectorStatus(true);
            isStopCache = false;
        }
    }


    public static void showLayoutInspector(Context context) {
        Intent intent = new Intent(context, DevelopToolsService.class);
        intent.putExtra(BUNDLE_KEY_ACTION, BUNDLE_VALUE_ACTION_SHOW_LAYOUT_INSPECTOR);
        context.startService(intent);
    }

    public static void setScanLayout(Context context, boolean isOpen) {
        Intent intent = new Intent(context, DevelopToolsService.class);
        intent.putExtra(BUNDLE_KEY_ACTION, BUNDLE_VALUE_ACTION_SHOW_SCAN_LAYOUT);
        intent.putExtra(BUNDLE_KEY_IS_OPEN_LAYOUT_VIEWER, isOpen);
        context.startService(intent);
    }
}
